import { name, version } from '../package.json'

export const stringifyCallbackParameterTransferSymbolKey = Symbol.for(`${name}:stringifyCallbackParameterTransfer`)

const _callbackMapKey = Symbol.for(`${name}@${version}:callbackMap`)

export const callbackMap: Map<number, Function> =
  (globalThis as any)[_callbackMapKey] ?? ((globalThis as any)[_callbackMapKey] = new Map())

export const asyncCallbackParameterTransfer = <Fn extends (...args: any[]) => any>(
  fn: Fn
): ((...args: Parameters<Fn>) => Promise<Awaited<ReturnType<Fn>>>) => {
  const newFn: (...args: Parameters<Fn>) => Promise<Awaited<ReturnType<Fn>>> = async (...args) => fn(...args)
  return newFn
}

export const stringifyCallbackParameterTransfer = <Fn extends (...args: any[]) => any>(fn: Fn): Fn => {
  const newFn = fn.bind(undefined)
  const fnString = fn.toString()
  Object.defineProperty(newFn, 'toString', { configurable: true, value: () => fnString })
  Object.defineProperty(newFn, stringifyCallbackParameterTransferSymbolKey, { value: true })
  return newFn as any
}
